(function (factory) {
    /* Global define */
    if (typeof define === 'function' && define.amd) {
        // AMD. Register as an anonymous module.
        define(['jquery'], factory);
    } else if (typeof module === 'object' && module.exports) {
        // Node/CommonJS
        module.exports = factory(require('jquery'));
    } else {
        // Browser globals
        factory(window.jQuery);
    }
}(function ($) {

	$.fxDialog = function (message, title, option, callback) {
        var events = {};

        var opt = $.extend({}, {
            id: 'dialog-' + (+new Date()),
            width: 400,
            height: 400,
            css: '',
            zindex: 99999,
            left: 0,
            top: 0,
            showOverlay: true,
            showHeader: true,
            showFooter: true,
            buttons: [
                {
                    name: "close",
                    type: "button",
                    id: "btn-close",
                    cssClass: "btn btn-default",
                    title: "Close",
                    action: null
                },
                {
                    name: "submit",
                    type: "submit",
                    id: "btn-submit",
                    cssClass: "btn btn-primary",
                    title: "Submit",
                    action: null
                }
            ]
        }, option);

        opt.left = opt.left === 0 ? (window.innerWidth - opt.width) / 2 : opt.left;

        var fstyle = 'position:absolute;display:none;left:' + opt.left + 'px;top:' + opt.top + 'px;z-index:' + opt.zindex + ';' + opt.css;
        var style = 'border:1px solid #d1d1d1;background:#fff;width:' + opt.width + 'px;';

        var frame = [
            '<div id="' + opt.id + '" class="dialog-frame" style="' + fstyle + '">',
            '<div class="dialog-box" style="' + style + '">',
            '<div class="dialog-header" style="padding:10px 15px;height:40px;clear:both;">',
            '<h1 class="dialog-title" style="float:left;font-size:16px;">' + (title || '') + '</h1>',
            '<div class="dialog-action" style="float:right;"><span class="dialog-close" style="display:block;float:right;padding:0 5px;cursor:pointer;font-size:12px;" title="Close">X</span></div>',
            '</div>',
            '<div class="dialog-body" style="padding:15px;">',
            '</div>',
            '<div class="dialog-footer" style="padding:15px;text-align:right;">',
            '</div>',
            '</div>',
            '</div>'
        ];

        var $modal = null, $overlay = null;
        if ($('body').find(opt.id).length === 0) {
            $modal = $(frame.join(''));

            if (!opt.showHeader) {
                $modal.find('.dialog-header').remove();
            }

            if (!opt.showFooter) {
                $modal.find('.dialog-footer').remove();
            } else {
                var $footer = $modal.find('.dialog-footer');

                var btnOption = {
                    name: "button",
                    type: "button",
                    id: "btn-button",
                    cssClass: "btn btn-primary",
                    title: "Button",
                    action: null,
                    events: [{name:null, handler: null}]
                };

                $.each(opt.buttons, function (i, bt) {
                    var btOpt = $.extend({}, btnOption, bt);
                    var evts = btOpt.events || [];
                    var btId = btOpt.id === 'btn-button' ? btOpt.id + i : btOpt.id;
                    var $btn = $('<button type="' + btOpt.type + '" name="' + btOpt.name + '" id="' + btId + '" class="' + btOpt.cssClass + '" style="margin-left:15px;">' + btOpt.title + '</button>');

                    if (bt.action && (typeof bt.action === 'function')) {
                        $btn.click(function (e) {
                            bt.action(e);
                        });
                    }


                    $.each(evts, function(i, evt) {
                        if (evt && evt.name && (typeof evt.handler === 'function')) {
                            $btn.on(evt.name, function(e) {
                                evt.handler(e);
                            });
                        }
                    });                    

                    $footer.append($btn);
                });
            }

            if (message) {
                var html = message instanceof jQuery ? message.clone() : message;
                $modal.find('.dialog-body').html(html);
            }

            $('body').append($modal);

            if (opt.showOverlay) {
                $overlay = $('<div id="overlay-' + opt.id + '" class="dialog-overlay" style="position: fixed;top: 0;bottom: 0;left: 0;right: 0;text-align: center;font-size: 0;overflow-y: auto;background-color: rgba(0,0,0,.4);z-index: ' + (opt.zindex - 1) + ';pointer-events: none;opacity: 0;transition: opacity .3s;"></div>');

                $('body').append($overlay);
            }
        } else {
            $modal = $('body').find(opt.id);
        }

        // 响应点击标题栏关闭按钮
        $modal.delegate('.dialog-close', 'click', function (e) {
            hide();

            trigger('close', e);
        });

        // 响应点击关闭按钮时
        $modal.delegate('.dialog-footer button[name="close"]', 'click', function (e) {
            hide();

            trigger('close', e);
        });

        // 单独响应表单提交
        $modal.delegate('.dialog-footer button[type="submit"]', 'click', function (e) {
            var $form = $modal.find('.dialog-body form');
            if ($form.length > 0) {
                $form[0].submit();

                trigger('submit', e);
            }
        });

        // 滚动页面时重新定位对话框位置
        $(window).on('scroll', function () {
            if (opt.top === 0) {
                var top = window.pageYOffset + (window.innerHeight - $modal.find('.dialog-box').height()) / 2;
                $modal.css({ "top": top + "px" });
            } else {
                $modal.css({ "top": (window.pageYOffset + opt.top) + "px" });
            }
        });

        // 响应回调方法
        $modal.delegate('.dialog-footer button', 'click', function (e) {            
            if (callback) {
                callback(e);
            }

            trigger('click', e);
        });

        // 保存事件
        function eventHandler(event, callback) {
            var handlers = events[event] || [];
            handlers.push(callback);

            events[event] = handlers;
        }

        // 响应事件
        function trigger(event, params) {
            var handlers = events[event] || [];

            $.each(handlers, function(i, handler) {
                if (typeof handler === 'function') {
                    handler(params);
                }
            });
        }

        // 显示对话框
        function show(message, title) {
            if ((message || '') !== '') {
                $modal.find('.dialog-body').html(message);
            }

            if (opt.showHeader && (title || '') !== '') {
                $modal.find('.dialog-title').html(title);
            }

            $modal.show();
            if (opt.top === 0) {
                var top = window.pageYOffset + (window.innerHeight - $modal.find('.dialog-box').height()) / 2;
                $modal.css({ "top": top + "px" });
            } else {
                $modal.css({ "top": opt.top + "px" });
            }

            if (opt.showOverlay && $overlay) {
                $overlay.css({ "opacity": 50 });
            }

            trigger('show', {});
        }

        // 隐藏对话框
        function hide() {
            $modal.hide();

            if (opt.showOverlay && $overlay) {
                $overlay.css({ "opacity": 0 });
            }

            trigger('hide', {});
        }

        // 返回对外暴露的方法
        return {
            id: opt.id,
            modal: $modal,
            show: show,
            hide: hide,
			open: show,
			close: hide,
            on: eventHandler
        };
    };

}));
